package vmo;

import shared.Vec2f;
import vmo.Tile.TileType;

public abstract class Actor_Character extends Actor {

	static final Vec2f m_statleft=new Vec2f(-0.3F,0);
	static final Vec2f m_statright=new Vec2f(0.3F,0);
	static final Vec2f m_statup=new Vec2f(0,0.3F);
	static final Vec2f m_statdown=new Vec2f(0,-0.3F);
	
	Actor_Character()
	{
		m_wheel=new ActionWheel();				
	}
	boolean getNewTile(float x0, float y0, float x1, float y1)
	{
		short xi=(short) x0;
		short yi=(short) y0;
		short xo=(short) x1;
		short yo=(short) y1;
		if (xi!=xo)
		{
			return true;
		}
		if (yi!=yo)
		{
			return true;
		}
		return false;
	}

	boolean RampCheck(float x, float y, short z)
	{
		if (z>14)
		{
			return false;
		}
		Tile t=m_interface.getTile(x, y, (byte) ((byte)z+1));
		if (t!=null)
		{
			if (t.m_type==TileType.FLOOR)
			{
				return true;
			}
		}	
		
		
		return false;
	}	
	
	void setFacing(byte direction)
	{
		
	}
	
	byte Movecheck(float x, float y, short z, boolean ramp)
	{
		Tile t=m_interface.getTile(x, y, (byte) z);
		if (t==null)
		{
			return 1;
		}
		switch (t.m_type)
		{
		case VOID:
			return -1;

		
		case FLOOR:
			if (t.m_widget<96 && t.m_widget>Byte.MIN_VALUE)
			{
				return 1;
			}
			return 0;


		case RAMP:		
			return 0;
			
		case WALL:
			if (ramp)
			{
				if (RampCheck(x,y,z))
				{
					return 2;
				}
			}
			return 1;
		}
		return (byte) 0;
	}
	
	void MoveZ(byte b, short z)
	{
		switch (b)
		{
		case -1:
			if (z>0)
			{
				setLayer((short) (z-1));
			}
			break;
		case 2:
			if (z<15)
			{
				setLayer((short) (z+1));
			}
			break;
		
		}
		
	}
	
	void Move(byte direction)
	{
		boolean ramp=false;
		float x= getPosition().x;
		float y=  getPosition().y;
		short z= (short) getLayer();
		Tile foot=m_interface.getTile(x, y, (byte) getLayer());
		if (foot!=null)
		{
			if (foot.m_type==TileType.RAMP)
			{
				ramp=true;
			}	
			byte tcomp;
			switch (direction)
			{
			case 0:
				tcomp=Movecheck(x+m_statdown.x,y+m_statdown.y,z,ramp);
				if (tcomp!=1)
				{
					if (getNewTile(x,y,x,y-0.1F))
					{
						MoveZ(tcomp,z);
					}
					AdjustPos(0,-0.1F);	
					setFacing((byte) 0);
				}
				break;
				
			case 2:
				Move((byte) 0);
				Move((byte) 4);
				break;
			
			case 4:
				tcomp=Movecheck(x+m_statright.x,y+m_statright.y,z,ramp);
				if (tcomp!=1)
				{
					if (getNewTile(x,y,x+0.1F,y))
					{
						MoveZ(tcomp,z);		
					}
					AdjustPos(0.1F,0);
					setFacing((byte) 1);
				}		
				
				break;
	
			case 6:
				Move((byte) 4);
				Move((byte) 8);
				break;		
				
			case 8:
				tcomp=Movecheck(x+m_statup.x,y+m_statup.y,z,ramp);
				if (tcomp!=1)
				{
					if (getNewTile(x,y,x,y+0.1F))
					{
						MoveZ(tcomp,z);		
					}
					AdjustPos(0,0.1F);	
					setFacing((byte) 2);	
				}	
				
				break;	
				
			case 10:
				Move((byte) 8);
				Move((byte) 12);
				break;
				
			case 12:
				tcomp=Movecheck(x+m_statleft.x,y+m_statleft.y,z,ramp);
				if (tcomp!=1)
				{
					if (getNewTile(x,y,x-0.1F,y))
					{
						MoveZ(tcomp,z);		
					}
					AdjustPos(-0.1F,0);	
					setFacing((byte) 3);	
				}	
				
				break;
			
			case 14:
				Move((byte) 0);
				Move((byte) 12);
				break;	
			
			}
		}
	}

	public void Action(byte action, byte direction,boolean write)
	{
		byte b=(byte) (action+(direction<<4));
		if (write)
		{
			m_wheel.Write(b);
		}
		switch (action)
		{
		case 1:
			Move(direction);
			break;
		
		
		}
	
	}	

	abstract void AdjustPos(Vec2f p);	
	
	abstract void AdjustPos(float x, float y);

	abstract void setLayer(short l);
	

}
